#ifndef CODEEDITOR_H
#define CODEEDITOR_H

#include <QPlainTextEdit>
#include <QObject>
#include <QTextBlockUserData>
#include <QMouseEvent>
#include <QWheelEvent>
#include "syntaxhighlighter.h"

class LineNumberArea;

class CodeEditor : public QPlainTextEdit
{
    Q_OBJECT

public:
    CodeEditor(QWidget *parent = nullptr);

    void lineNumberAreaPaintEvent(QPaintEvent *event);
    int lineNumberAreaWidth();

    // 自动缩进和括号配对相关方法
    void autoIndent();
    void matchParentheses();
    int findMatchingParenthesis(QTextCursor cursor, QChar open, QChar close);
    void insertPlainTextWithIndent(const QString &text);

    // 设置函数
    void setAutoIndentEnabled(bool enabled) { autoIndentEnabled = enabled; }
    void setParenthesesMatchingEnabled(bool enabled) { parenthesesMatchingEnabled = enabled; }

    // 行号区鼠标事件（用于折叠/展开）
    void lineNumberAreaMousePressEvent(QMouseEvent *event);

    // 折叠相关
    void toggleFoldAt(int blockNumber);

    void setBreakpoints(const QList<int> &bp);

signals:
    void zoomInRequested();
    void zoomOutRequested();
    void lineNumberAreaClicked(int line);
    void breakpointsChanged(const QList<int> &bp);

protected:
    void resizeEvent(QResizeEvent *event) override;
    void keyPressEvent(QKeyEvent *e) override;
    void wheelEvent(QWheelEvent *event) override;

private slots:
    void updateLineNumberAreaWidth(int newBlockCount);
    void highlightCurrentLine();
    void updateLineNumberArea(const QRect &rect, int dy);

private:
    // —— 折叠实现细节 ——
    struct BlockData : public QTextBlockUserData {
        bool folded = false;          // 当前块是否处于折叠状态（仅对起始块有效）
        int  endBlockNumber = -1;     // 折叠对应的结束块号（含结束块）
    };

    // 判断某块是否可折叠；如可折叠则返回对应的结束块号
    bool isFoldableBlock(const QTextBlock &block, int *endBlockNumber = nullptr) const;
    void setFolded(const QTextBlock &startBlock, bool folded, int endBlockNumber);
    QTextBlock blockAtY(int y) const;

    QList<int> breakpoints;

private:
    QWidget *lineNumberArea;
    SyntaxHighlighter *highlighter;

    // 自动缩进相关
    bool autoIndentEnabled;
    int tabSpaces;

    // 括号配对相关
    bool parenthesesMatchingEnabled;
    QList<QTextEdit::ExtraSelection> parenthesesSelections;

    // 折叠指示宽度
    static constexpr int kFoldIndicatorWidth = 14; // 行号区左侧为折叠符保留的像素宽度
};

class LineNumberArea : public QWidget
{
public:
    LineNumberArea(CodeEditor *editor) : QWidget(editor), codeEditor(editor) {
        setMouseTracking(true);
    }

    QSize sizeHint() const override {
        return QSize(codeEditor->lineNumberAreaWidth(), 0);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        codeEditor->lineNumberAreaPaintEvent(event);
    }

    void mousePressEvent(QMouseEvent *event) override {
        codeEditor->lineNumberAreaMousePressEvent(event);
        QWidget::mousePressEvent(event);
    }

private:
    CodeEditor *codeEditor;
};

#endif // CODEEDITOR_H

